<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="vue.js"></script>
    <script src="vue-router.js"></script>
</head>

<body>
    <div id="app">
        <router-link to="/user/pangchao">pangchao</router-link>
        <router-link to="/tiger/pangchao">tiger</router-link>
        <router-view></router-view>
    </div>

    <script>
        'use strict';
        /*
            before : 在...之前
            after  : 在...之后
            
            导航守卫

                “导航”表示路由正在发生改变。
                正如其名，vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
                有多种机会植入路由导航过程中：全局的, 单个路由独享的, 或者组件级的。
                记住参数或查询的改变并不会触发进入/离开的导航守卫。
                你可以通过观察 $route 对象来应对这些变化，或使用 beforeRouteUpdate 的组件内守卫。
        */
        let user = {
            props: ['name'],
            template: '<div> 使用 Props 代替 $route.params.name 方法,User name is {{ name }} </div>',
            beforeRouteEnter(to, from, next) {
                // 在渲染该组件的对应路由被 confirm 前调用
                // 不！能！获取组件实例 `this`
                // 因为当守卫执行前，组件实例还没被创建
                // console.log(to);
                // console.log(from);
                // console.log(next);
                next({
                    // 传入的参数值不要添加 # 号
                    // 浏览器会解析 ＃ 号为id
                    path: '/getid/001'
                })
            },
            beforeRouteUpdate(to, from, next) {
                // 在当前路由改变，但是该组件被复用时调用
                // 举例来说，对于一个带有动态参数的路径 /foo/:id，在 /foo/1 和 /foo/2 之间跳转的时候，
                // 由于会渲染同样的 Foo 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
                // 可以访问组件实例 `this`
            },
            beforeRouteLeave(to, from, next) {
                // 导航离开该组件的对应路由时调用
                // 可以访问组件实例 `this`
            }
        };
        let tiger = {
            props: ['name'],
            template: '<div> 使用 Props 代替 $route.params.name 方法,User name is {{ name }} </div>',
        };

        let userBefore = {
            props: ["id"],
            template: '<div> User id is {{ id }} </div>'
        }

        const router = new VueRouter({
            routes: [{
                path: '/user/:name',
                component: user,
                props: true
            }, {
                path: '/getid/:id',
                component: userBefore,
                props: true
            }, {
                /*
                    路由独享的守卫
                    可以在路由配置上直接定义 beforeEnter 守卫：
                */
                path: '/tiger/:name',
                // redirect: '/user/:name',
                component: tiger,
                beforeEnter(to, from, next) {
                    console.log('2' + to);
                    console.log('2' + from);
                    console.log('2' + next);
                }
            }]
        })

        //全局前置守卫
        router.beforeEach((to, from, next) => {
            // to and from are both route objects. must call `next`.
            /*
            当一个导航触发时，全局前置守卫按照创建顺序调用。
            守卫是异步解析执行，此时导航在所有守卫 resolve 完之前一直处于 等待中。

            每个守卫方法接收三个参数：
                to: Route: 即将要进入的目标 路由对象
                from: Route: 当前导航正要离开的路由
                next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
                    next(): 进行管道中的下一个钩子。如果全部钩子执行完了，则导航的状态就是 confirmed (确认的)。
                    next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮)，那么 URL 地址会重置到 from 路由对应的地址。
                    next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断，然后进行一个新的导航。你可以向 next 传递任意位置对象，且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
                    next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例，则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
            确保要调用 next 方法，否则钩子就不会被 resolved。
        */
            console.log(to)
            console.log(from)
            console.log(next)
        });

        /*
        全局解析守卫 2.5.0 新增
            在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。
            这和 router.beforeEach 类似，区别是在导航被确认之前，同时在所有组件内守卫和异步路由组件被解析之后，解析守卫就被调用。

        全局后置钩子
            可以注册全局后置钩子，然而和守卫不同的是，这些钩子不会接受 next 函数也不会改变导航本身：
        */
        router.afterEach((to, from) => {
            // to and from are both route objects.
            console.log(to);
            console.log(from)
        })

        new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>